package com.recharge.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Maps;
import com.recharge.common.domain.PageDO;
import com.recharge.common.enums.ErrorCode;
import com.recharge.common.result.ResultDO;
import com.recharge.common.result.ResultSupport;
import com.recharge.common.util.ArithUtils;
import com.recharge.common.util.BeanUtilsExtends;
import com.recharge.common.util.Constant;
import com.recharge.common.util.SnowflakeIdWorker;
import com.recharge.core.entity.*;
import com.recharge.core.mapper.ProviderGoodsMapper;
import com.recharge.domain.query.ProviderGoodsQueryDO;
import com.recharge.domain.vo.CardDO;
import com.recharge.domain.vo.CardVoucherDO;
import com.recharge.domain.vo.ProviderGoodsDO;
import com.recharge.domain.vo.UserLoginDO;
import com.recharge.service.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static com.recharge.common.util.Constant.*;
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.toList;

/**
 * <p>
 * 商品供应表 服务实现类
 * </p>
 *
 * @author Reagan
 * @since 2020-10-20
 */
@Service
public class ProviderGoodsServiceImpl extends ServiceImpl<ProviderGoodsMapper, ProviderGoodsEntity> implements ProviderGoodsService {

    private Logger logger = LoggerFactory.getLogger(this.getClass().getName());
    @Autowired
    private GoodsService goodsService;
    @Autowired
    private ProviderService providerService;
    @Autowired
    private GoodsProviderService goodsProviderService;
    @Autowired
    private CardVoucherService cardVoucherService;


    /**
     * 供应商品
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDO provideGoods(CardDO domain, int provideMethodType) {
        Date currentTime = Calendar.getInstance().getTime();
        ResultDO result = new ResultSupport();
        //不存在此供卡类型供应商
        ProviderEntity provider = providerService.getOne(Wrappers.<ProviderEntity>lambdaQuery().eq(ProviderEntity::getProviderNo, domain.getProviderNo()).eq(ProviderEntity::getType, PROVIDER_TYPE_2));
        if (provider == null) {
            logger.info(result.getErrorCode().getMsg());
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.API_PROVIDER_NOT_ERROR);
            return result;
        }
        //卡密数量不正
        if (CollectionUtils.isEmpty(domain.getCardVoucheres()) || domain.getCardVoucheres().size() != domain.getQuartity()) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.API_CARD_GOODS_QUARTITY_ERROR);
            return result;
        }
        Map<Integer, List<CardVoucherDO>> cards = domain.getCardVoucheres().parallelStream().collect(groupingBy(CardVoucherDO::getGoodsNo));

        for (Map.Entry<Integer, List<CardVoucherDO>> entry : cards.entrySet()) {
            Integer no = entry.getKey();
            List<CardVoucherDO> cardList = entry.getValue();
            GoodsEntity goodsEntity = goodsService.getOne(Wrappers.<GoodsEntity>lambdaQuery().eq(GoodsEntity::getGoodsNo, no));
            //不存在该商品
            if (goodsEntity == null) {
                result.setSuccess(false);
                result.setErrorCode(ErrorCode.API_CARD_GOODS_NOT_ERROR);
                logger.info(result.getErrorCode().getMsg());
                return result;
            }

            //生成卡密供应记录
            ProviderGoodsEntity entity = new ProviderGoodsEntity();
            entity.setId(SnowflakeIdWorker.getId());
            entity.setDenomination(goodsEntity.getDenomination());
            entity.setCreateDate(currentTime);
            entity.setModifiDate(currentTime);
            entity.setIsDelete(IS_DELETE_FALSE);
            entity.setStatus(PROVIDER_CARD_UNKNOW);
            entity.setServiceProvider(domain.getServiceProvider() == null ? goodsEntity.getServiceProvider() : domain.getServiceProvider());
            entity.setRegionType(domain.getRegionType() == null ? goodsEntity.getRegionType() : domain.getRegionType());
            entity.setCityCode(StringUtils.isEmpty(domain.getCityCode()) ? goodsEntity.getCityCode() : domain.getCityCode());
            entity.setProvinceCode(StringUtils.isEmpty(domain.getProvinceCode()) ? goodsEntity.getProvinceCode() : domain.getProvinceCode());
            entity.setQuantity(cardList.size());
            //entity.setCostPrice((long) (cardList.size() * ArithUtils.mul(goodsEntity.getDenomination().doubleValue(), provider.get())));
            entity.setGoodsId(goodsEntity.getId());
            entity.setGoodsNo(goodsEntity.getGoodsNo());
            entity.setProviderId(provider.getId());
            entity.setType(domain.getType());
            entity.setTotalAmount(goodsEntity.getDenomination() * cardList.size());
            baseMapper.insert(entity);

            //更新商品库存
            goodsEntity.setStock(goodsEntity.getStock() + cardList.size());
            goodsService.updateById(goodsEntity);

            //存储卡密
            List<CardVoucherDO> voucherVoList = cardList.stream().peek(i -> {
                i.setId(SnowflakeIdWorker.getId());
                i.setGoodsNo(no);
                i.setProviderId(provider.getId());
                i.setProviderNo(provider.getProviderNo());
                i.setDenomination(goodsEntity.getDenomination());
                i.setCreateMothod(provideMethodType);
            }).collect(toList());
            ResultDO resultDO = cardVoucherService.insertAll(voucherVoList);
            if (!resultDO.isSuccess()) {
                entity.setStatus(PROVIDER_CARD_SUCCESS);
            } else {
                entity.setStatus(PROVIDER_CARD_FAIL);
            }

            baseMapper.updateById(entity);

        }
        return result;
    }

    public ResultDO add(ProviderGoodsDO domain) {

        GoodsEntity goodsEntity = goodsService.getOne(Wrappers.<GoodsEntity>lambdaQuery().eq(GoodsEntity::getGoodsNo, domain.getGoodsNo()));
        ProviderEntity providerEntity = providerService.getOne(Wrappers.<ProviderEntity>lambdaQuery().eq(ProviderEntity::getId, domain.getProviderId()));

        ProviderGoodsEntity entity = new ProviderGoodsEntity();

        ResultDO result = BeanUtilsExtends.copy(entity, domain);
        if (!result.isSuccess()) {
            logger.info("error code：" + result.getErrorCode().getCode() + " msg" + result.getErrorCode().getMsg());
            return result;
        }

        entity.setProviderId(domain.getProviderId());
        entity.setGoodsId(goodsEntity.getId());
        entity.setGoodsNo(goodsEntity.getGoodsNo());
        entity.setDenomination(goodsEntity.getDenomination());
        entity.setDenomination(goodsEntity.getDenomination());

        entity.setCreateDate(Calendar.getInstance().getTime());
        entity.setModifiDate(entity.getCreateDate());
        entity.setModifier(entity.getCreator());
        //修改商品库存


        boolean res = false;
        try {
            res = this.save(entity);
        } catch (Exception e) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.info("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }

        //判断r的值是否小于0.如果小于0 就代表添加失败
        if (!res) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.CARD_PROVIDER_ADD_PROVIDER_GOODS_ERROR);
            logger.info("error code：" + ErrorCode.CARD_PROVIDER_ADD_PROVIDER_GOODS_ERROR.getCode() + " msg" + ErrorCode.CARD_PROVIDER_ADD_PROVIDER_GOODS_ERROR.getMsg());
            return result;
        }

        return result;
    }


    public ResultDO edit(ProviderGoodsDO domain) {

        ProviderGoodsEntity entity = new ProviderGoodsEntity();

        ResultDO result = BeanUtilsExtends.copy(entity, domain);
        if (!result.isSuccess()) {
            logger.info("error code：" + result.getErrorCode().getCode() + " msg" + result.getErrorCode().getMsg());
            return result;
        }

        entity.setModifiDate(Calendar.getInstance().getTime());

        boolean res = false;
        try {
            res = this.updateById(entity);
        } catch (Exception e) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.info("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }

        //判断r的值是否小于0.如果小于0 就代表添加失败
        if (!res) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.CARD_PROVIDER_EDIT_PROVIDER_GOODS_ERROR);
            logger.info("error code：" + ErrorCode.CARD_PROVIDER_EDIT_PROVIDER_GOODS_ERROR.getCode() + " msg" + ErrorCode.CARD_PROVIDER_EDIT_PROVIDER_GOODS_ERROR.getMsg());
            return result;
        }

        return result;
    }


    public ResultDO get(String id) {

        ResultDO result = new ResultSupport();
        ProviderGoodsEntity entity = null;

        try {
            entity = this.getById(id);
        } catch (Exception e) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.info("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }

        ProviderGoodsDO domain = getDomain(entity);

        result.setModel(ResultDO.FIRST_MODEL_KEY, domain);

        return result;
    }


    public ResultDO remove(String id, String modifier) {
        ResultDO result = new ResultSupport();

        ProviderGoodsEntity entity = new ProviderGoodsEntity();

        entity.setModifiDate(Calendar.getInstance().getTime());
        entity.setModifier(modifier);
        entity.setId(id);
        entity.setIsDelete(Constant.IS_DELETE);

        boolean res = false;
        try {
            res = this.updateById(entity);
        } catch (Exception e) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.info("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }

        //判断r的值是否小于0.如果小于0 就代表添加失败
        if (!res) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.CARD_PROVIDER_DELETE_PROVIDER_GOODS_ERROR);
            logger.info("error code：" + ErrorCode.CARD_PROVIDER_DELETE_PROVIDER_GOODS_ERROR.getCode() + " msg" + ErrorCode.CARD_PROVIDER_DELETE_PROVIDER_GOODS_ERROR.getMsg());
            return result;
        }

        return result;
    }


    @Override
    public ResultDO find(ProviderGoodsQueryDO query) {
        ProviderGoodsEntity entity = new ProviderGoodsEntity();
        ResultDO result = BeanUtilsExtends.copy(entity, query);
        if (!result.isSuccess()) {
            logger.info("error code：" + result.getErrorCode().getCode() + " msg" + result.getErrorCode().getMsg());
            return result;
        }

        Map<String, Object> params = Maps.newHashMap();
        params.put("goodsId", query.getGoodsId());
        params.put("goodsNo", query.getGoodsNo());
        params.put("providerId", query.getProviderId());
        params.put("providerNo", query.getProviderNo());
        params.put("denomination", query.getDenomination());
        params.put("regionType", query.getRegionType());
        params.put("provinceCode", query.getProvinceCode());
        params.put("providerName", StringUtils.isEmpty(query.getProviderName()) ? null : "%" + query.getProviderName() + "%");
        params.put("cityCode", query.getCityCode());
        params.put("serviceProvider", query.getServiceProvider());
        if (query.getSelectTime() != null && query.getSelectTime().length >= 2) {
            params.put("startTime", StringUtils.isEmpty(query.getSelectTime()[0]) ? null : Long.parseLong(query.getSelectTime()[0]) / 1000);
            params.put("endTime", StringUtils.isEmpty(query.getSelectTime()[1]) ? null : Long.parseLong(query.getSelectTime()[1]) / 1000);
        }
        params.put("goodsName", StringUtils.isEmpty(query.getGoodsName()) ? null : "%" + query.getGoodsName() + "%");

        Page<Map<String, Object>> page = new Page<>(query.getCurrentPage(), query.getPageSize());

        IPage<Map<String, Object>> iPage = null;

        try {
            iPage = baseMapper.selectOtherPage(page, params);
        } catch (Exception e) {
            e.printStackTrace();
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.info("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }
        List<ProviderGoodsDO> doList = getDomainList(iPage.getRecords());
        PageDO<ProviderGoodsDO> pageDO = new PageDO<>();

        pageDO.setCurrentPage(iPage.getCurrent());
        pageDO.setPageCount(iPage.getPages());
        pageDO.setPageSize(iPage.getSize());
        pageDO.setRowCount(iPage.getTotal());
        pageDO.setData(doList);
        result.setModel(ResultDO.FIRST_MODEL_KEY, pageDO);
        return result;
    }

    private ProviderGoodsDO getDomain(ProviderGoodsEntity entity) {

        //判断房源对象是否为空，为空就返回 空，不为空就进行下面的代码
        if (entity == null) return null;
        ProviderGoodsDO domain = new ProviderGoodsDO();

        domain = BeanUtilsExtends.copyProperties(domain, entity) ? domain : null;

        //判断拷贝数据到Dto对象是否成功，如果成功则返回domian，如果不成功就返回空
        return domain;
    }

    private List<ProviderGoodsDO> getDomainList(List<Map<String, Object>> list) {
        //创建一个名为dolist的房源do类型的 list集合
        List<ProviderGoodsDO> doList = new ArrayList<ProviderGoodsDO>();

        //判断传入的list的集合的size是否大于0
        if (list.size() > 0) {
            //大于0是，遍历list，创建do类型的对象 调用getdomain方法
            for (var result : list) {
                //ProviderGoodsDO domain = BeanUtils.mapToBean(result, ProviderGoodsDO.class);
                ProviderGoodsDO d = new ProviderGoodsDO();
                d.setProviderId(result.getOrDefault("providerId", "").toString());
                d.setGoodsId(result.getOrDefault("goodsId", "").toString());
                d.setGoodsNo(Integer.parseInt(result.getOrDefault("goodsNo", "0").toString()));
                d.setTitle(result.getOrDefault("title", "").toString());
                d.setProviderNo(result.getOrDefault("providerNo", "").toString());
                d.setDenomination(Long.parseLong(result.getOrDefault("denomination", "0").toString()));
                d.setQuantity(Integer.parseInt(result.getOrDefault("quantity", "0").toString()));
                d.setTotalAmount(Long.parseLong(result.getOrDefault("totalAmount", "0").toString()));
                d.setServiceProvider(Integer.parseInt(result.getOrDefault("serviceProvider", "0").toString()));
                d.setRegionType(Integer.parseInt(result.getOrDefault("regionType", "0").toString()));
                d.setProvinceCode(result.getOrDefault("provinceCode", "").toString());
                d.setCityCode(result.getOrDefault("cityCode", "").toString());
                d.setType(Integer.parseInt(result.getOrDefault("type", "0").toString()));
                d.setProviderTime((Date) result.get("providerTime"));
                d.setStatus(Integer.parseInt(result.getOrDefault("status", "1").toString()));
                d.setProviderName(result.getOrDefault("providerName", "").toString());
                doList.add(d);
            }
        } else {
            return null;
        }
        return doList;
    }


}
